package csu.softwaremetric.controller;

import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.text.DecimalFormat;

@RestController
public class UseCaseAnalyzerController {





//    @PostMapping("/uploadFile")
//    public String uploadFile(@RequestParam("file") MultipartFile file) {
//        try {
//            File convFile = new File("D:/dasanxia/" + file.getOriginalFilename());
//            file.transferTo(convFile);
//            return convFile.getAbsolutePath();
//        } catch (IOException e) {
//            e.printStackTrace();
//            return "File upload failed!";
//        }
//    }

    //第一个页面，前端传来一个XML文件，解析文件中的内容计算出UUCP返回给前端
    @PostMapping("/calculateUUCP")
    public JSONObject calculateUUCP(@RequestParam("file") MultipartFile file)  {
        int uucp;
        JSONObject ob = new JSONObject();
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(file.getInputStream());
            doc.getDocumentElement().normalize();

            // 获取所有的packagedElement节点
            NodeList packagedElements = doc.getElementsByTagName("packagedElement");

            int roleCount = 0;
            int useCaseCount = 0;
            int complexRoleCount = 0;
            int simpleRoleCount = 0;
            int mediumRoleCount = 0;

            for (int i = 0; i < packagedElements.getLength(); i++) {
                Element element = (Element) packagedElements.item(i);
                String type = element.getAttribute("xmi:type");

                if (type.equals("uml:Actor")) {
                    roleCount++;
                    String roleName = element.getAttribute("name");
                    if (roleName.contains("Person")) {
                        complexRoleCount++;
                    } else if (roleName.contains("System")) {
                        simpleRoleCount++;
                    } else {
                        mediumRoleCount++;
                    }
                } else if (type.equals("uml:UseCase")) {
                    useCaseCount++;
                }
            }
            System.out.println(simpleRoleCount);
            System.out.println(mediumRoleCount);
            System.out.println(complexRoleCount);
            int uaw = simpleRoleCount + 2 * mediumRoleCount + 3 * complexRoleCount;
//            int uucw = 5 * simpleUseCases + 10 * averageUserCases + 15 * complexUserCases;
            int uucw = 10 * useCaseCount;
            uucp = uaw + uucw;
            ob.put("STATUS", "SUCCESS");
            ob.put("MSG", "成功");
            ob.put("UUCP", uucp);

            return ob;
        }catch (Exception e) {
            e.printStackTrace();
            ob.put("STATUS", "Failure");
            ob.put("MSG", "失败");

            return ob;
        }
    }

    //第二个页面，前端传来技术复杂性因子中各个因子的数量，后端计算出TCF的值返回前端
    //这里用一个类来存放了各个因子的数量，是否可以这样做？
    @PostMapping("/calculateTCF")
    public JSONObject calculateTCF(@RequestBody JSONObject json){
        //TechFactors techFactors = new TechFactors();
        double TCF;
        JSONObject ob = new JSONObject();
        int tech1 = json.getIntValue("tech1");
        int tech2 = json.getIntValue("tech2");
        int tech3 = json.getIntValue("tech3");
        int tech4 = json.getIntValue("tech4");
        int tech5 = json.getIntValue("tech5");
        int tech6 = json.getIntValue("tech6");
        int tech7 = json.getIntValue("tech7");
        int tech8 = json.getIntValue("tech8");
        int tech9 = json.getIntValue("tech9");
        int tech10 = json.getIntValue("tech10");
        int tech11 = json.getIntValue("tech11");
        int tech12 = json.getIntValue("tech12");
        int tech13 = json.getIntValue("tech13");



        double tFactor = 2*tech1+ tech2 + tech3 + tech4 + tech5 +
                0.5*tech6+0.5*tech7+2*tech8+ tech9+tech10+
                tech11 +tech12+tech13;
        TCF = 0.6 + 0.01 * tFactor;

        ob.put("STATUS", "SUCCESS");
        ob.put("MSG", "成功");
        ob.put("TCF", TCF);

        return ob;
    }

    //第三个页面，前端传来了环境因子，后端计算出EF返回给前端
    @PostMapping("/calculateEF")
    public JSONObject calculateEF(@RequestBody JSONObject json){
        double EF;
        JSONObject ob = new JSONObject();
        int f1 = json.getIntValue("f1");
        int f2 = json.getIntValue("f2");
        int f3 = json.getIntValue("f3");
        int f4 = json.getIntValue("f4");
        int f5 = json.getIntValue("f5");
        int f6 = json.getIntValue("f6");
        int f7 = json.getIntValue("f7");
        int f8 = json.getIntValue("f8");
        double eFactor = (1.5 * f1) + (0.5 * f2) + f3
                + (0.5 * f4) + f5 + (2 * f6) - f7
                - f8;
        System.out.println(eFactor);
        EF = 1.400 - (0.030 * eFactor);
        System.out.println(EF);
        DecimalFormat df = new DecimalFormat("#.###");
        EF = Double.valueOf(df.format(EF));
        System.out.println(EF);

        ob.put("STATUS", "SUCCESS");
        ob.put("MSG", "成功");
        ob.put("EF", EF);

        return ob;
    }

    //第四个页面，根据上面计算出来的uucp、TCF、EF计算出UPC返回给前端
    @PostMapping("/calculateUPC")
    public JSONObject calculateUPC(@RequestBody JSONObject json) {
        double UPC;
        JSONObject ob = new JSONObject();
            UPC = json.getIntValue("UUCP") * json.getDoubleValue("TCF") * json.getDoubleValue("EF");
            DecimalFormat df = new DecimalFormat("#.###");
            UPC = Double.valueOf(df.format(UPC));
            System.out.println(UPC);
            ob.put("STATUS", "SUCCESS");
            ob.put("MSG", "成功");
            ob.put("UCP", UPC);

            return ob;

    }
}
